﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Data.Linq;
using System.Text;
using System.IO;
using MyMoviesBrowserLibrary.MyMovies;
using System.Xml.Linq;

namespace MyMoviesBrowserLibrary
{
    public class MyMoviesBrowserBusiness
    {

        public static MyMoviesBrowserDataContext GetNewMyMoviesBrowserDataContext()
        {
            return new MyMoviesBrowserDataContext(string.Format(@"Data Source={0}\MYMOVIES;Initial Catalog='MyMoviesBrowser';Persist Security Info=True;User ID=sa;Password=t9AranuHA7", Settings.Default.MyMoviesServerName));
        }
        
        public static int GetPlaybackTime(string filePath)
        {
            MyMoviesBrowserDataContext ctx = GetNewMyMoviesBrowserDataContext();
            MediaPlayback mp = ctx.MediaPlaybacks.FirstOrDefault(m => m.MediaUrl == filePath);
            if (mp == null)
                return 0;
            return mp.PlaybackTime;
        }
        public static void SetPlaybackTime(string filePath, int seconds)
        {
            MyMoviesBrowserDataContext ctx = GetNewMyMoviesBrowserDataContext();
            MediaPlayback mp = ctx.MediaPlaybacks.FirstOrDefault(m => m.MediaUrl == filePath);
            if (mp == null)
                mp = new MediaPlayback() { MediaUrl = filePath };
            mp.PlaybackTime = seconds;

            if (mp.MediaPlaybackId == 0)
                ctx.MediaPlaybacks.InsertOnSubmit(mp);
            ctx.SubmitChanges();
        }
        public static void SetPlayed(string filePath, bool played)
        {
            MyMoviesBrowserDataContext ctx = GetNewMyMoviesBrowserDataContext();
            MediaPlayback mp = ctx.MediaPlaybacks.FirstOrDefault(m => m.MediaUrl == filePath);
            if (mp == null)
                mp = new MediaPlayback() { MediaUrl = filePath };
            mp.Played = played;

            if (mp.MediaPlaybackId == 0)
                ctx.MediaPlaybacks.InsertOnSubmit(mp);
            ctx.SubmitChanges();
        }
        public static bool CheckWatched(string filePath)
        {
            MyMoviesBrowserDataContext ctx = GetNewMyMoviesBrowserDataContext();
            MediaPlayback mp = ctx.MediaPlaybacks.FirstOrDefault(m => m.MediaUrl == filePath);
            if (mp == null)
                return false;
            return mp.Played;
        }

        public static void MarkTrailerAsWatched(MovieTrailer movieTrailer, bool played)
        {
            MyMoviesBrowserDataContext ctx = GetNewMyMoviesBrowserDataContext();
            ctx.ExecuteCommand("update MovieTrailers set Watched = @p0 where MovieTrailerId = @p1",played, movieTrailer.MovieTrailerId);
            //movieTrailer.Watched = true;
        }        

        public static List<string> GetSimilarTrailers(MyMovies.Title title, int number)
        {

            MyMoviesDataContext ctx = MyMoviesBusiness.GetNewMyMoviesDataContext();
            MyMoviesBrowserDataContext ctx2 = GetNewMyMoviesBrowserDataContext();
            List<MyMovies.Genre> genres = (from tg in ctx.TitleGenres
                      join g in ctx.Genres on tg.intGenre equals g.intId
                      where tg.intTitle == title.intId
                      select g).ToList();

            List<string> genreStrings = genres.Select(g=>g.nvcName).ToList();
            for (int i = 0; i < genreStrings.Count; i++)
			{
                if (genreStrings[i] == "Suspense/Thriller")
                    genreStrings[i] = "Thriller";
                else if (genreStrings[i] == "Action")
                    genreStrings[i] = "Action and Adventure";
                else if (genreStrings[i] == "Adventure")
                    genreStrings[i] = "Action and Adventure";
                else if (genreStrings[i] == "Science-Fiction")
                    genreStrings[i] = "Science Fiction";
			}


            var trailers = from mg in ctx2.MovieTrailer_Genres
                           where genreStrings.Contains(mg.Genre.GenreDesc)
                           select mg.MovieTrailer;

            var watched = trailers.Where(t => t.Watched == true).ToList();
            var notwatched = trailers.Where(t => t.Watched == false).ToList();

            List<MovieTrailer> selectedTrailers = new List<MovieTrailer>();
            Random random = new Random();

            while (notwatched.Count > 0 && selectedTrailers.Count < number)
            {
                int index = random.Next(0, notwatched.Count);
                MovieTrailer trailer = notwatched[index];
                selectedTrailers.Add(trailer);
                notwatched.Remove(trailer);
            }

            while (watched.Count > 0 && selectedTrailers.Count < number)
            {
                int index = random.Next(0, watched.Count);
                MovieTrailer trailer = watched[index];
                selectedTrailers.Add(trailer);
                watched.Remove(trailer);
            }

            List<string> paths = new List<string>();

            foreach (MovieTrailer mt in selectedTrailers)
            {
                DirectoryInfo di = new DirectoryInfo(mt.MovieFolder);
                if (di.Exists)
                {
                    FileInfo fi = di.GetFiles("*.mov").OrderBy(f => f.LastWriteTime).LastOrDefault();
                    if (fi != null)
                        paths.Add(fi.FullName);
                    else
                    {
                        fi = di.GetFiles("*.wmv").OrderBy(f => f.LastWriteTime).LastOrDefault();
                        if (fi != null)
                            paths.Add(fi.FullName);
                    }
                }
            }

            return paths;
        }

        public static MovieTrailer ImportFolder(string movieDirectory)
        {
            MyMoviesBrowserDataContext ctx = MyMoviesBrowserBusiness.GetNewMyMoviesBrowserDataContext();
            DataLoadOptions options = new DataLoadOptions();
            options.LoadWith<MovieTrailer>(m => m.MovieTrailer_Genres);
            options.LoadWith<MovieTrailer>(m => m.MovieTrailer_Persons);
            options.LoadWith<MovieTrailer>(m => m.Director);
            options.LoadWith<MovieTrailer>(m => m.Rating);
            options.LoadWith<MovieTrailer_Person>(m => m.Person);
            options.LoadWith<MovieTrailer_Genre>(m => m.Genre);
            ctx.LoadOptions = options;

            FileInfo xmlFile = new FileInfo(Path.Combine(movieDirectory, "movie.xml"));
            if (!xmlFile.Exists)
                return null;

            XDocument doc = XDocument.Load(xmlFile.FullName);
            XElement xMovie = doc.Element("movieinfo");
            if (xMovie == null)
                return null;

            int appleId = 0;

            DateTime temp;
            if (xMovie.Attribute("id") != null)
                appleId = int.Parse(xMovie.Attribute("id").Value);
            if (appleId == 0)
                return null;

            MovieTrailer movieTrailer = ctx.MovieTrailers.SingleOrDefault(m => m.MovieInfoId == appleId);

            if (movieTrailer == null)
            {
                movieTrailer = new MovieTrailer();
                movieTrailer.MovieInfoId = appleId;
            }

            movieTrailer.MovieFolder = movieDirectory;

            if (xMovie.Element("info") != null)
            {
                XElement info = xMovie.Element("info");
                if (info.Element("title") != null)
                {
                    movieTrailer.Title = info.Element("title").Value;
                    movieTrailer.SortTitle = movieTrailer.Title;
                    if (movieTrailer.SortTitle.ToLower().StartsWith("the "))
                    {
                        movieTrailer.SortTitle = movieTrailer.SortTitle.Substring(4) + ", The";
                    }
                }
                if (info.Element("runtime") != null)
                    movieTrailer.Runtime = info.Element("runtime").Value;

                // get rating
                if (info.Element("rating") != null)
                {
                    string strRating = info.Element("rating").Value;
                    if (!string.IsNullOrEmpty(strRating))
                    {
                        Rating rating = ctx.Ratings.SingleOrDefault(r => r.RatingDesc == strRating);
                        if (rating == null)
                        {
                            rating = new Rating() { RatingDesc = strRating };
                            ctx.Ratings.InsertOnSubmit(rating);
                        }
                        rating.MovieTrailers.Add(movieTrailer);
                    }
                }

                // add to studio
                if (info.Element("studio") != null)
                {
                    string strStudio = info.Element("studio").Value;
                    if (!string.IsNullOrEmpty(strStudio))
                    {
                        Studio studio = ctx.Studios.SingleOrDefault(s => s.StudioName == strStudio);
                        if (studio == null)
                        {
                            studio = new Studio() { StudioName = strStudio };
                            ctx.Studios.InsertOnSubmit(studio);
                        }
                        studio.MovieTrailers.Add(movieTrailer);
                    }
                }


                if (info.Element("postdate") != null)
                {
                    if (DateTime.TryParse(info.Element("postdate").Value, out temp))
                        movieTrailer.PostDate = temp;
                }
                if (info.Element("releasedate") != null)
                {
                    if (DateTime.TryParse(info.Element("releasedate").Value, out temp))
                        movieTrailer.ReleaseDate = temp;
                }
                if (info.Element("director") != null)
                {
                    string strDirector = info.Element("director").Value;
                    if (!string.IsNullOrEmpty(strDirector))
                    {
                        Person director = ctx.Persons.SingleOrDefault(p => p.PersonName == strDirector);
                        if (director == null)
                        {
                            director = new Person() { PersonName = strDirector };
                            ctx.Persons.InsertOnSubmit(director);
                            ctx.SubmitChanges();
                        }
                        director.MovieTrailers.Add(movieTrailer);
                    }
                }
                if (info.Element("description") != null)
                    movieTrailer.Description = info.Element("description").Value;
            }

            if (xMovie.Element("genre") != null)
            {
                foreach (XElement xGenre in xMovie.Element("genre").Descendants("name"))
                {
                    Genre genre = ctx.Genres.SingleOrDefault(g => g.GenreDesc == xGenre.Value);
                    if (genre == null)
                    {
                        genre = new Genre() { GenreDesc = xGenre.Value };
                        ctx.Genres.InsertOnSubmit(genre);
                        ctx.SubmitChanges();
                    }

                    MovieTrailer_Genre mg = movieTrailer.MovieTrailer_Genres.SingleOrDefault(m => m.Genre == genre);
                    if (mg == null)
                    {
                        mg = new MovieTrailer_Genre();
                        movieTrailer.MovieTrailer_Genres.Add(mg);
                        genre.MovieTrailer_Genres.Add(mg);
                    }
                }
            }

            movieTrailer.PosterLocation = Path.Combine(movieDirectory, "folder.jpg");

            if (xMovie.Element("cast") != null)
            {
                foreach (XElement xCast in xMovie.Element("cast").Descendants("name"))
                {
                    Person person = ctx.Persons.SingleOrDefault(g => g.PersonName == xCast.Value);
                    if (person == null)
                    {
                        person = new Person() { PersonName = xCast.Value };
                        ctx.Persons.InsertOnSubmit(person);
                        ctx.SubmitChanges();
                    }
                    MovieTrailer_Person mp = movieTrailer.MovieTrailer_Persons.SingleOrDefault(m => m.Person == person);
                    if (mp == null)
                    {
                        mp = new MovieTrailer_Person();
                        movieTrailer.MovieTrailer_Persons.Add(mp);
                        person.MovieTrailer_Persons.Add(mp);
                    }
                }
            }

            movieTrailer.DateUpdated = DateTime.Now;

            if (movieTrailer.MovieTrailerId == 0)
                ctx.MovieTrailers.InsertOnSubmit(movieTrailer);

            ctx.SubmitChanges();

            return movieTrailer;
        }        
    }
}
